test(custom-lint): rule⑥ self-exclusion 回帰テスト + Bundle g-1 stale cleanup (Phase d P-3 繰上げ)#141
Conversation
…entries 削除 + analysis.md P-3 完了反映
…帰テスト追加 + analysis.md P-3 完了反映 (順位 68 / Bundle d / Phase d P-3 繰上げ)
📝 Walkthrough概要PR 変更点ドッグフード進捗とタスク追跡
no-ephemeral-todo-reference Lint ルールテスト
推定コードレビュー労力🎯 2 (シンプル) | ⏱️ ~12 分 関連の可能性がある PR
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/hooks-post-tool-linter/src/main.rs (1)
1699-1711: ⚡ Quick winself-exclusion test の前提条件を明示化することを推奨
本テストは deployed
.claude/custom-lint-rules.tomlファイルに対して rule を適用し、self-trigger しないことを検証しています。テストの実効性は extensions list に"toml"が含まれることに依存していますが、この前提が明示されていないため、将来の変更で extensions から"toml"が削除された場合、テストは pass するものの実際には TOML ファイルがスキャンされない (silent test degradation) リスクがあります。テスト冒頭で前提を明示する assertion を追加することを推奨します。
🛡️ 提案する改善
#[test] fn no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml() { + let rule = no_ephemeral_todo_reference_rule(); + assert!( + rule.extensions.contains(&"toml".to_string()), + "self-exclusion test requires 'toml' in extensions list to actually scan the TOML file" + ); + let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("..") .join("..") .join(".claude") .join("custom-lint-rules.toml"); - let rules = compile_test_rules(vec![no_ephemeral_todo_reference_rule()]); + let rules = compile_test_rules(vec![rule]); let violations = run_custom_rules(path.to_str().unwrap(), &rules); assert!( violations.is_empty(), "self-exclusion invariant broken: rule⑥ self-triggered on deployed custom-lint-rules.toml" ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hooks-post-tool-linter/src/main.rs` around lines 1699 - 1711, The test no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml currently assumes TOML files are scanned but doesn't assert that the linter's configured extensions include "toml"; add an explicit assertion at the start of this test that the extensions list used by the custom rules contains "toml" (i.e., call the same helper/config function that run_custom_rules or compile_test_rules uses to obtain file extensions, assert extensions.contains("toml")), so the test will fail loudly if future changes remove TOML from the scanned extensions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/hooks-post-tool-linter/src/main.rs`:
- Around line 1699-1711: The test
no_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml currently
assumes TOML files are scanned but doesn't assert that the linter's configured
extensions include "toml"; add an explicit assertion at the start of this test
that the extensions list used by the custom rules contains "toml" (i.e., call
the same helper/config function that run_custom_rules or compile_test_rules uses
to obtain file extensions, assert extensions.contains("toml")), so the test will
fail loudly if future changes remove TOML from the scanned extensions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7cf5d53b-b6bb-47a5-9cf4-27cb7d773342
📒 Files selected for processing (5)
docs/local-llm-offload-analysis.mddocs/todo-summary.mddocs/todo5.mddocs/todo6.mdsrc/hooks-post-tool-linter/src/main.rs
💤 Files with no reviewable changes (1)
- docs/todo5.md
…1/103/106) (#146) * docs(todo,analysis): post-merge-feedback PR #145 採用 2 件登録 + Phase D D-1 完了反映 PR #145 (D-1) merge 後の post-merge-feedback で採用された 2 件 (Tier 3 #1 + #3) を todo 系列に登録し、analysis.md の Phase D section に D-1 land 状況と副産物を反映する。 順位 116 (Tier 3 XS、PR #145 T3-#1): - ADR-040 step_timeout 説明に sublinear / KV cache locality clarification 追記 - 実測値 600s 採択 / 保守上限 720s / sublinear 性の KV cache 根拠 順位 117 (Tier 3 S、PR #145 T3-#3): - coding-style.md § Cross-File Reference Lifecycle に ephemeral → permanent 知識移管 edit order を追記 - 3 ステップ原則 (① permanent target 先行作成・validate → ② 参照追加 → ③ 参照元削除) analysis.md Phase D section 更新: - D-1 land 状況 (PR #145、298 行、ZERO findings APPROVE) を table の状態列に反映 - 順位 115 を D-2 前 critical path として明示 - D-1 dogfood outcome として 4 項目記録 (skip 理由 / workflow gap 発見 / ADR-040 fix / migration codify) 順位 115 (Tier 1) の rationale に「post-merge-feedback Tier 1 #1 で再 validate 済」を追記。 * feat(hooks-post-tool-linter): D-2 lint rule code touch (順位 101/103/106) Phase D dogfood の 2 本目 (D-2)。lint rule の test gap + struct doc + self-exclusion guards を bundled。 順位 101 (PR #140 T1-#1 採用): rule⑧ depth-1 root MD edge case test 2 件追加 - md_no_docs_relative_detects_root_level_back_reference (CLAUDE.md fixture) - md_no_docs_relative_detects_root_readme_back_reference (README.md fixture) - 「fire = true positive」整理を doc comment と test 名で明示 - root-level MD からの ../docs/ 参照は repo 外を指す broken link で真陽性が正しい挙動 順位 103 (PR #140 T1-#3 採用): CustomRule struct に lint runner field reference doc comment 追加 - サポート field 一覧 (id/pattern/severity/message/extensions/why/fix/example) を /// で記述 - planned field (paths、順位 102) も併記し設計-実装 gap を構造的に予防 - custom-lint-rules.toml 冒頭コメントに main.rs CustomRule struct への動線追加 順位 106 (PR #141 T2-#1 採用): self-exclusion invariant test に 2 false-green guards 追加 - assert!(path.exists()) — deployed TOML 削除 / 移動時の silent pass 抑止 - assert!(extensions contains "toml") — rule scope 変更時の silent degradation 抑止 - 各 assertion message に silent degradation のリスクと由来 (順位 106 / PR #141 T2-#1) を inline で記述 cargo test pass: hooks-post-tool-linter 95 tests (新規 2 + 既存 +1 強化、ZERO regression)。 PR #145 = D-1 と同様、lint_screen dogfood は順位 115 (env var override) land 前のため skip。
Summary
Phase d roster の P-3 (繰上げ) として Bundle d (順位 68 =
no-ephemeral-todo-referenceself-exclusion invariant 回帰テスト) を land。3 commits 構成: P-2 feedback layer / stale todo cleanup (Bundle g-1 land 済発見) / P-3 implementation。変更内容
Commit 1: 順位 101-105 登録 + analysis.md P-2 完了反映 (P-2 feedback layer carry-over)
PR #140 (Phase d P-2 = rule⑧ no-docs-relative) merge 後の post-merge-feedback で採用された 5 件 を todo に登録。analysis.md の P-2 row を ✅ 完了化 + classifier preview metrics + fallback rate 100% trend signal を outcome section として記載。
pathsfilter を lint runner に実装PR #140 T2 #1 (大文字バリアント test 必須化) は 不採用: memory
feedback_no_unenforced_rules.mdの追加観測として「Tier 2 偽装の必須化ルール」検知 signal 3 項目を codify。Commit 2: 順位 85+86 (Bundle g-1) は PR #125 で land 済を反映 — stale todo cleanup
P-3 着手時に
src/cli-pr-monitor/src/stages/monitor.rsのcompute_verdictを読んだ瞬間、既にreview_state == "not_found" || "pending"guard が存在し、12 件の verdict transition tests が pass することを発見。jj logで PR #125 (2026-05-07 merge) で実装済 と確認。PR #125 がfeedback_todo_no_history.md("完了タスクは todo から削除") に違反 し、todo entry 削除を忘れたため、3 日後の PR #138 (Phase d kickoff prep) で stale な docs/todo-summary.md を読んだ際に「pending」と誤認 → roster の P-3 に Bundle g-1 を組入れ。本 commit で:
docs/todo5.mdの 順位 85/86 detail entry 削除 (-43 行)docs/todo-summary.mdの 順位 85/86 行削除 (Bundle g paragraph も ✅ 完了化)docs/local-llm-offload-analysis.mdの P-3 row を「P-3roster から除外」に変更、後続 P-4/P-5 を P-3/P-4 に繰上げ新 memory
feedback_verify_task_not_already_done.mdを追加: todo 着手時に jj log + 既存 test で land 済確認する手順を codify。本件と同型の事故を recovery layer として防ぐ。Commit 3: rule⑥ self-exclusion 回帰テスト追加 + analysis.md P-3 完了反映 (本 PR の核)
src/hooks-post-tool-linter/src/main.rsに 6 件のno_ephemeral_todo_*test を追加。配置先は既存testsmod 内 (md_no_docs_relative_* test group の隣)。no_ephemeral_todo_detects_concrete_digit_referencedocs/todo3.md形式 → fire (TP)no_ephemeral_todo_detects_zero_digit_formdocs/todo.md(zero digit) 形式 → fire (zero-digit edge case)no_ephemeral_todo_skips_letter_placeholderdocs/todoN.md(N = letter) → skipno_ephemeral_todo_skips_asterisk_literaldocs/todo*.md(literal*) → skipno_ephemeral_todo_only_targets_listed_extensions_md_skipped.md拡張子は対象外 → skipno_ephemeral_todo_self_exclusion_invariant_holds_on_deployed_toml.claude/custom-lint-rules.toml自身は self-trigger しないことを assert (本 task の核)Self-trigger 事故の対処
本 test 実装中、PostToolUse lint で rule⑥ self-trigger + comment-lint-rust (Bundle Z #B-α) 違反を検出 (試験運用層が動作した好事例):
docs/todo3.md/docs/todo.md文字列が source 中に直接書かれて rule⑥ に hit//コメントが Bundle Z #B-α (Rust 非 doc コメント禁止) に違反対処 (= 本 test が future 防止しようとしている self-trigger anti-pattern の dogfood 検証):
format!()で動的構築 (source に literal を残さないbuild_concrete_digit_fixture(3)/build_zero_digit_fixture()等のヘルパー化)//コメント全削除 (test 名 + assertion message で意図を表現)これにより本 test 自身も rule⑥ + comment lint 両方で clean に通る状態を達成。
analysis.md P-3 完了反映
P-3 (繰上げ) row を ✅ 完了化 + P-3 dogfood outcome section を追加。
Phase d P-3 dogfood signal (classifier preview のみ、real pipeline 未実行)
P-1 / P-2 と同方針 (commit pollution 回避):
Fallback rate trend (累積): 3/3 = 100%。Phase d guide §3 の kill-switch criteria (3/5 = 60% で停止) は real pipeline 経由なら 既に発動超過。順位 98 (
num_ctxoverflow detection) を Phase d 結果集約より先に実装することを強く推奨 (kill-switch 厳密判定の前提整備)。Latency variance signal: P-1=23s / P-2=46s / P-3=11s の振れ幅は input size と弱相関 (P-2 が最短入力で最長 latency) → mistral 内部状態 (cold/warm context) が支配的要因の仮説を強化。real pipeline 計測時は cold start 回避の warmup 戦略の設計が必要。
Test plan
cargo test -p hooks-post-tool-linter— 93/93 pass (87 既存 + 6 新規)pnpm deploy:hooksでビルド・デプロイ確認Out of scope
num_ctxoverflow detection): P-3 fallback で再々確認した重要性を本 PR でも記述したが、実装は別 PR (Phase d 結果集約より先に実装推奨)techbook-ledger/auto-review-fix-vcへの hook 反映は別タイミングSummary by CodeRabbit
リリースノート
Documentation
Tests